/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.tabbedproperties.section;

import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.uml2.uml.AggregationKind;
import org.eclipse.uml2.uml.Artifact;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.VisibilityKind;

import com.cea.papyrus.core.editpart.IUMLElementEditPart;
import com.cea.papyrus.core.tabbedproperties.PropertyViewSection;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagram.classdiagram.editpart.AssociationEditPart;


/**
 * Section for Association ends (Roles)
 */

public class RoleSection extends PropertyViewSection {


	/**
	 * The separator.
	 */
	private org.eclipse.swt.widgets.Label separator;

	/**
	 * The role name.
	 */
	private Text[] roleName            = new Text[2];

	/**
	 * The association type.
	 */
	private Combo[] associationType    = new Combo[2];

	/**
	 * The combo multiplicity.
	 */
	private CCombo[] comboMultiplicity = new CCombo[2];

	/**
	 * The is derived.
	 */
	private Button[] isDerived         = new Button[2];

	/**
	 * The is navigable.
	 */
	private Button[] isNavigable       = new Button[2];

	/**
	 * The check box visibility.
	 */
	private Button[][] checkBoxVisibility    = new Button[2][VisibilityKind.VALUES.size()];


	//private FocusListener[] roleNameListener;

	/**
	 * Creates the controls.
	 * 
	 * @param tabbedPropertySheetPage the tabbed property sheet page
	 * @param parent the parent
	 */
	@Override
	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage) {

		super.createControls(parent, tabbedPropertySheetPage);
		Composite composite
		= getWidgetFactory().createFlatFormComposite(parent);

		// Create the separation between roles
		createSeparator(composite);

		// Create roles
		createRoleArea(composite, 0);
		createRoleArea(composite, 1);
	}

	/**
	 * Creates the separator.
	 * 
	 * @param father the father
	 */
	private void createSeparator(Composite father) {
		separator = getWidgetFactory().createSeparator(father, SWT.VERTICAL);
		separator.setVisible(false);

		// Place separator in the center
		FormData data = new FormData();
		data.left = new FormAttachment(50, -50);
		data.top = new FormAttachment(0, 0);
		separator.setLayoutData(data);
	}

	/**
	 * Creates the role area.
	 * 
	 * @param father the father
	 * @param roleNumber the role number
	 */
	private void createRoleArea(Composite father, final int roleNumber) {

		// Role names
		createRoleName(father, roleNumber);
		// AssociationType
		createAssociationType(father, roleNumber);
		// Qualifiers (isNavigable, isDerived)
		createQualifierButtons(father, roleNumber);
		// Visibility handling
		createVisibilityButtons(father, roleNumber);
		// Multiplicity handling
		createMultiplicityCombo(father, roleNumber);
	}

	/**
	 * Creates the role name.
	 * 
	 * @param father the father
	 * @param roleNumber the role number
	 */
	private void createRoleName(Composite father, final int roleNumber) {

		// Create roleName area
		roleName[roleNumber] = getWidgetFactory().createText(father, "");
		roleName[roleNumber].setEditable(true);
		// Add listeners
		roleName[roleNumber].addFocusListener(
				new FocusListener() {
					public void focusGained(FocusEvent e) {
					}

					public void focusLost(FocusEvent e) {
						Property role = getRole(roleNumber);
						if (role == null) {
							return;
						}
						String name = roleName[roleNumber].getText();
						role.setName((name!=null)? name.trim() : "");
					}
				});

		// Place roleName
		FormData data = new FormData();
		if (roleNumber == 0) {
			data.left = new FormAttachment(0, STANDARD_LABEL_WIDTH);
			data.right = new FormAttachment(separator, 0);
		} else {
			data.left = new FormAttachment(separator, STANDARD_LABEL_WIDTH);
			data.right = new FormAttachment(100, -100);
		}
		data.top = new FormAttachment(0, 0);
		roleName[roleNumber].setLayoutData(data);

		// Create a label
		CLabel label = getWidgetFactory().createCLabel(father, "Role:");
		// Place the label
		data = new FormData();
		if (roleNumber == 0) {
			data.left = new FormAttachment(0, 0);
		} else {
			data.left = new FormAttachment(separator, 0);
		}
		data.right = new FormAttachment(roleName[roleNumber],
				-ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(roleName[roleNumber], 0, SWT.CENTER);
		label.setLayoutData(data);
	}

	/**
	 * Creates the association type.
	 * 
	 * @param father the father
	 * @param roleNumber the role number
	 */
	private void createAssociationType(Composite father, final int roleNumber) {

		associationType[roleNumber] = new Combo(father, SWT.NONE);
		// Add combo selection possibilities
		associationType[roleNumber].add("Simple");
		associationType[roleNumber].add("Aggregation");
		associationType[roleNumber].add("Composition");

		// Add listener on combo
		associationType[roleNumber].addSelectionListener(
				new SelectionListener() {
					public void widgetSelected(SelectionEvent e) {
						Property role = getRole(roleNumber);
						if (role == null) {
							return;
						}
						setAggregationKindValue(role, roleNumber, associationType[roleNumber]);
					}

					public void widgetDefaultSelected(SelectionEvent e){
					}
				});

		// Set combo position
		FormData data = new FormData();
		if (roleNumber == 0) {
			data.left = new FormAttachment(0, STANDARD_LABEL_WIDTH);
		} else {
			data.left = new FormAttachment(separator, STANDARD_LABEL_WIDTH);
		}
		data.top = new FormAttachment(roleName[roleNumber], 0);
		associationType[roleNumber].setLayoutData(data);

		// Add a label
		CLabel label = getWidgetFactory().createCLabel(father, "Kind:");
		data = new FormData();
		if (roleNumber == 0) {
			data.left = new FormAttachment(0, 0);
		} else {
			data.left = new FormAttachment(separator, 0);
		}
		data.right = new FormAttachment(associationType[roleNumber],
				-ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(associationType[roleNumber], 0, SWT.CENTER);
		label.setLayoutData(data);
	}

	/**
	 * Creates the qualifier buttons.
	 * 
	 * @param father the father
	 * @param roleNumber the role number
	 */
	private void createQualifierButtons(Composite father, final int roleNumber) {
		createNavigableButton(father, roleNumber);
		createDerivedButton(father, roleNumber);
	}

	/**
	 * Creates the navigable button.
	 * 
	 * @param father the father
	 * @param roleNumber the role number
	 */
	private void createNavigableButton(Composite father, final int roleNumber) {
		isNavigable[roleNumber] = getWidgetFactory().createButton(father, "isNavigable", SWT.CHECK);

		// Set position
		FormData data = new FormData();		
		if (roleNumber == 0) {
			data.left = new  FormAttachment(0, STANDARD_LABEL_WIDTH);
		} else {
			data.left = new  FormAttachment(separator, STANDARD_LABEL_WIDTH);
		}
		data.top = new FormAttachment(associationType[roleNumber], 0);
		isNavigable[roleNumber].setLayoutData(data);

		// Set listeners
		isNavigable[roleNumber].addSelectionListener(
				new SelectionListener() {
					public void widgetSelected(SelectionEvent e) {

						// Retrieve current role
						Property role    = getRole(roleNumber);
						Classifier ownerClass = getOppositeEndType(roleNumber);
						
						if ((role == null) || (ownerClass == null)) {
							return;
						}
						
						Association association = (Association) getElement();
						// Delete the notifiers
						// ((Notifier) role).eAdapters().clear();

						if(isNavigable[roleNumber].getSelection() == false) {  					
							association.getOwnedEnds().add(role);
							if (ownerClass instanceof Class) {
								((Class)ownerClass).getOwnedAttributes().remove(role);
							} else if (ownerClass instanceof Artifact) {
								((Artifact)ownerClass).getOwnedAttributes().remove(role);
							}
							role.setAssociation(association);

						} else {
							if (ownerClass instanceof Class) {
								((Class)ownerClass).getOwnedAttributes().add(role);
							} else if (ownerClass instanceof Artifact) {
								((Artifact)ownerClass).getOwnedAttributes().add(role);
							}
							association.getOwnedEnds().remove(role);
							role.setAssociation(association);
						}
					} 

					public void widgetDefaultSelected(SelectionEvent e){
					}
				}); 

		// Add a label
		CLabel navigableLabel = getWidgetFactory().createCLabel(father, "Qualifiers:");
		data = new FormData();
		if (roleNumber == 0) {
			data.left = new FormAttachment(0, 0);
		} else {
			data.left = new FormAttachment(separator, 0);
		}
		data.right = new FormAttachment(isNavigable[roleNumber],
				-ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(isNavigable[roleNumber], 0, SWT.CENTER);
		navigableLabel.setLayoutData(data);
	}

	protected boolean isOppositeEndElementImport(int roleNumber) {
		boolean isElementImport = true;
		if (roleNumber == 0) {
			isElementImport = isEndTypeElementImport(1);
		} else {
			isElementImport = isEndTypeElementImport(0);
		}

		return isElementImport;
	}
	
	protected boolean isEndTypeElementImport(int roleNumber) {
		// Checking parameters		
		if ((roleNumber > 1) || (roleNumber < 0)) {
			Debug.error(this, "role number should be 0 or 1 instead of "+roleNumber, channel);
			return false;
		}

		boolean isElementImport = false;
		
		IUMLElementEditPart editpart = getGraphicalElement();
		// get the end edit part (knows which element is linked, but outline?!)
		if(editpart instanceof AssociationEditPart) {
			AssociationEditPart associationEditPart = (AssociationEditPart)editpart;
			if(roleNumber == 1) {
				// source edit part => role 1
				if(associationEditPart.getSource() instanceof IUMLElementEditPart) {
					isElementImport = ((IUMLElementEditPart)associationEditPart.getSource()).isElementImport();
				}
			} else {
				// target edit part => role 0
				if(associationEditPart.getTarget() instanceof IUMLElementEditPart) {
					isElementImport = ((IUMLElementEditPart)associationEditPart.getTarget()).isElementImport();
				}
			}
		}

		return isElementImport;
	}

	/**
	 * Creates the derived button.
	 * 
	 * @param father the father
	 * @param roleNumber the role number
	 */
	private void createDerivedButton(Composite father, final int roleNumber) {
		isDerived[roleNumber] = getWidgetFactory().createButton(father, "isDerived", SWT.CHECK);

		// Set button position
		FormData data = new FormData();		
		data.left = new  FormAttachment(isNavigable[roleNumber], ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(isNavigable[roleNumber], 0, SWT.CENTER);
		isDerived[roleNumber].setLayoutData(data);

		// Set listeners
		isDerived[roleNumber].addSelectionListener(
				new SelectionListener() {
					public void widgetSelected(SelectionEvent e) {

						// Retrieve current role
						Property role    = getRole(roleNumber);
						role.setIsDerived(isDerived[roleNumber].getSelection());
					} 

					public void widgetDefaultSelected(SelectionEvent e){
					}
				}); 
	}

	/**
	 * Creates the visibility buttons.
	 * 
	 * @param father the father
	 * @param roleNumber the role number
	 */
	private void createVisibilityButtons(Composite father, final int roleNumber) {
		// Visibility handling
		Iterator it = VisibilityKind.VALUES.iterator();
		while (it.hasNext()) {
			VisibilityKind currentVisibility = (VisibilityKind) it.next();
			int visibilityIndex = currentVisibility.getValue();

			Button previousButton = null;
			if (currentVisibility.getValue() > 0) {
				previousButton = checkBoxVisibility[roleNumber][visibilityIndex - 1];
			}

			checkBoxVisibility[roleNumber][visibilityIndex]
			                               = createVisibilityButton(
			                            		   father
			                            		   , roleNumber
			                            		   , currentVisibility
			                            		   , previousButton);
		}

		// Add label
		CLabel label = getWidgetFactory().createCLabel(father, "Visibility:");
		FormData data = new FormData();

		data.right = new FormAttachment(checkBoxVisibility[roleNumber][0],
				-ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(checkBoxVisibility[roleNumber][0], 0, SWT.CENTER);

		if (roleNumber == 0) {
			data.left = new FormAttachment(0, 0);
		} else {
			data.left = new FormAttachment(separator, 0);
		}		

		label.setLayoutData(data);
	}

	/**
	 * Creates the visibility button.
	 * 
	 * @param kind the kind
	 * @param left the left
	 * @param father the father
	 * @param roleNumber the role number
	 * 
	 * @return the button
	 */
	private Button createVisibilityButton(Composite father, final int roleNumber, final VisibilityKind kind, Button left) {
		FormData data = new FormData();
		Button visibility = getWidgetFactory().createButton(father, kind.getLiteral(), SWT.RADIO);

		if (left != null) {
			data.left = new FormAttachment(left, ITabbedPropertyConstants.HSPACE);
		} else {
			if (roleNumber == 0) {
				data.left = new FormAttachment(0, STANDARD_LABEL_WIDTH);
			} else {
				data.left = new FormAttachment(separator, STANDARD_LABEL_WIDTH);				
			}
		}

		data.top   = new FormAttachment(isNavigable[roleNumber], 0);
		visibility.setLayoutData(data);

		// Add listener
		visibility.addSelectionListener(
				new SelectionListener() {
					public void widgetSelected(SelectionEvent e) {
						Property role = getRole(roleNumber);
						if (role == null) {
							return;
						}
						role.setVisibility(kind);
					}

					public void widgetDefaultSelected(SelectionEvent e){
					}
				});

		return visibility;
	}

	/**
	 * Creates the multiplicity combo.
	 * 
	 * @param roleNumber the role number
	 * @param father the father
	 */
	private void createMultiplicityCombo(Composite father, final int roleNumber) {

		comboMultiplicity[roleNumber] = getWidgetFactory().createCCombo(father, SWT.NONE);
		CLabel label = getWidgetFactory().createCLabel(father, "Multiplicity:");

		comboMultiplicity[roleNumber].setEditable(true);

		comboMultiplicity[roleNumber].add("0");
		comboMultiplicity[roleNumber].add("0..1");
		comboMultiplicity[roleNumber].add("0..*");
		comboMultiplicity[roleNumber].add("1");
		comboMultiplicity[roleNumber].add("1..*");
		comboMultiplicity[roleNumber].add("*");   

		FormData dataCombo = new FormData();
		dataCombo.top      = new FormAttachment(checkBoxVisibility[roleNumber][0], 0);			
		comboMultiplicity[roleNumber].setLayoutData(dataCombo);

		FormData dataLabel = new FormData();
		dataLabel.right    = new FormAttachment(comboMultiplicity[roleNumber], -ITabbedPropertyConstants.HSPACE);
		dataLabel.top      = new FormAttachment(comboMultiplicity[roleNumber], 0, SWT.CENTER);
		label.setLayoutData(dataLabel);

		if (roleNumber == 1) {
			// Attached to the separator
			dataCombo.left = new FormAttachment(separator, STANDARD_LABEL_WIDTH);
			dataLabel.left  = new FormAttachment(separator, 0);
		} else {
			// Attached to left border
			dataCombo.left = new FormAttachment(0, STANDARD_LABEL_WIDTH);
			dataLabel.left  = new FormAttachment(0, 0);
		}

		// Add listeners
		comboMultiplicity[roleNumber].addModifyListener(
				new ModifyListener () {

					/* (non-Javadoc)
					 * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
					 */
					public void modifyText(ModifyEvent e) {
						Property role = getRole(roleNumber);
						if (role == null) {
							return;
						}
						setMultiplicityValue(role, comboMultiplicity[roleNumber]);
					}
				});
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
	 */
	@Override
	public void refresh() {
		// Call refresh for each role number
		refresh(0);
		refresh(1);
	}

	/**
	 * Refresh the given role property display
	 * @param roleNumber the role number
	 */
	private void refresh(int roleNumber) {
		Property role = getRole(roleNumber);
		if (role == null) {
			return;
		}
		refreshRoleName(roleNumber, role);
		refreshQualifiers(roleNumber, role);
		refreshAssociationType(roleNumber, role);
		refreshVisibility(roleNumber, role);
		refreshMultiplicity(roleNumber, role);
	}

	/**
	 * Refresh role name.
	 * 
	 * @param role the role
	 * @param roleNumber the role number
	 */
	private void refreshRoleName(int roleNumber, Property role) {	
		if (!roleName[roleNumber].isDisposed()) {
			String name = role.getName();
			roleName[roleNumber].setText((name!=null)?name.trim():"");
		}
	}

	/**
	 * Refresh qualifiers.
	 * 
	 * @param role the role
	 * @param roleNumber the role number
	 */
	private void refreshQualifiers(int roleNumber, Property role) {
		if(!isNavigable[roleNumber].isDisposed() && !isDerived[roleNumber].isDisposed()){
			isNavigable[roleNumber].setSelection(role.isNavigable());
			isDerived[roleNumber].setSelection(role.isDerived());
			
			// check element import for navigation
			// retrieve if opposite end type is an element import
			// if it is an element import, can not set navigability to true
			// as the proeprty should be added to the element import (read only element)
			boolean isOppositeEndElementImport = isOppositeEndElementImport(roleNumber);
			if(isOppositeEndElementImport) {
				isNavigable[roleNumber].setEnabled(false);
			} else if ((role.getType() instanceof org.eclipse.uml2.uml.Actor) ||
					(role.getType() instanceof org.eclipse.uml2.uml.UseCase)){
				isNavigable[roleNumber].setEnabled(false);
			}else{
				isNavigable[roleNumber].setEnabled(true);
			}
			
			
		}
	}

	/**
	 * Refresh association type.
	 * 
	 * @param role the role
	 * @param roleNumber the role number
	 */
	private void refreshAssociationType(int roleNumber, Property role) {
		if(! associationType[roleNumber].isDisposed()){
			setAssociationType(role, associationType[roleNumber]);
		}
	}

	/**
	 * Refresh visibility.
	 * 
	 * @param role the role
	 * @param roleNumber the role number
	 */
	private void refreshVisibility(int roleNumber, Property role) {
		Iterator it = VisibilityKind.VALUES.iterator();
		while (it.hasNext()) {
			VisibilityKind currentVisibility = (VisibilityKind) it.next();
			int visibilityIndex = currentVisibility.getValue();
			if (!checkBoxVisibility[roleNumber][visibilityIndex].isDisposed()){

				if (role.getVisibility().equals(currentVisibility)) {
					checkBoxVisibility[roleNumber][visibilityIndex].setSelection(true);
				} else {
					checkBoxVisibility[roleNumber][visibilityIndex].setSelection(false);
				}
			}
		}
	}

	/**
	 * Refresh multiplicity.
	 * 
	 * @param role the role
	 * @param roleNumber the role number
	 */
	private void refreshMultiplicity(int roleNumber, Property role) {
		if (!comboMultiplicity[roleNumber].isDisposed()){
			String lower = String.valueOf(role.getLower());
			String upper = String.valueOf(role.getUpper());
			if(upper.equals("-1")) {
				comboMultiplicity[roleNumber].setText(lower+".."+"*");
			} else {
				comboMultiplicity[roleNumber].setText(lower+".."+upper);
			}
		}
	}

	/**
	 * Gets the end type.
	 * 
	 * @param roleNumber the role number
	 * 
	 * @return the end type
	 */
	private Classifier getEndType(int roleNumber) {

		// Checking parameters
		if ((roleNumber > 1) || (roleNumber < 0)) {
			IllegalArgumentException e = new IllegalArgumentException();
			e.printStackTrace();
			return null;
		}

		// Checking current element	
		if(!(getElement() instanceof Association)) {
			return null;
		}
		Association association = (Association) getElement();
		List endTypes = association.getEndTypes();
		if(endTypes.size() ==  2) {
			return (Classifier) endTypes.get(roleNumber);
		} else if(endTypes.size() == 1) {
			return (Classifier) endTypes.get(0);
		}
		return null;
	}


	/**
	 * Gets the opposite end type.
	 * @param roleNumber the role number
	 * @return the opposite end type
	 */
	private Classifier getOppositeEndType(int roleNumber) {
		Classifier clazz;
		if (roleNumber == 0) {
			clazz = getEndType(1);
		} else {
			clazz = getEndType(0);
		}
		return clazz;
	}

	/**
	 * Gets the role.
	 * @param roleNumber the role number
	 * @return the role
	 */
	private Property getRole(int roleNumber) {

		// Checking parameters
		if ((roleNumber > 1) || (roleNumber < 0)) {
			IllegalArgumentException e = new IllegalArgumentException();
			e.printStackTrace();
			return null;
		}

		// Checking current element	
		if(!(getElement() instanceof Association)) {
			return null;
		}
		Association association = (Association) getElement();
		List memberEnds = association.getMemberEnds();

		if(memberEnds.size() != 2) {
			return null;
		}

		Property role = (Property) memberEnds.get(roleNumber);

		return role;
	}
	
	/**
	 * Gets the opposite role of the given role at position <code>roleNumber<code>
	 * @param roleNumber the role number of the role for which opposite is searched
	 * @return the opposite property or <code>null</code> if not found 
	 */
	private Property getOppositeRole(int roleNumber) {
		int oppositeRoleNumber = 0;
		if(roleNumber == 0) {
			oppositeRoleNumber = 1;
		}
		return getRole(oppositeRoleNumber);
	}

	/**
	 * Sets the association type.
	 * @param assocType the association type
	 * @param property the property
	 */
	private void setAssociationType(Property property, Combo assocType) {
		AggregationKind type = property.getAggregation();

		if(type==AggregationKind.NONE_LITERAL) {
			assocType.select(0);
		} else if(type==AggregationKind.SHARED_LITERAL) {
			assocType.select(1);
		} else if(type==AggregationKind.COMPOSITE_LITERAL) {
			assocType.select(2);
		}
	}

	/**
	 * Sets the aggregation kind value.
	 * @param assocType the assoc type
	 * @param roleNumber the role number of the modified role
	 * @param property the property
	 */
	private void setAggregationKindValue(Property property, int roleNumber, Combo assocType) {
		int type = assocType.getSelectionIndex();

		if(type==0) {
			property.setAggregation(AggregationKind.NONE_LITERAL);
		} else if(type==1) {
			property.setAggregation(AggregationKind.SHARED_LITERAL);
		} else if(type==2) {
			property.setAggregation(AggregationKind.COMPOSITE_LITERAL);
			
			// should modify multiplicity of opposite property
			// when setting to Composite
			Property oppositeRole = getOppositeRole(roleNumber);
			if (oppositeRole == null) {
				return;
			}
			
			// check if mutliplicity of opposite property is valid 
			boolean isValid = isMultiplicityValid(oppositeRole);
			if(!isValid) {
				// default is [0..1] for aggregation for opposite property
				// get the other role
				setMultiplicityValue(oppositeRole, 0, 1);
				refresh();
			}
		}
	}

	/**
	 * Check if the multiplicity of a property is valid, if this is a
	 * composite property. It should be [0..1] or [1..1].
	 * @param property the property to check
	 * @return <code>true</code> if the multiplicity is valid
	 */
	private boolean isMultiplicityValid(Property property) {
		// lower value can be 0 or 1
		if(property.getLower()>1) {
			return false;
		}
		// upper value can be 1
		if(property.getUpper()!=1) {
			return false;
		}
		return true;
	}

	/**
	 * Sets the multiplicity for the given property, depending on the result of 
	 * the specified CCombo
	 * @param property the property to be modified 
	 * @param comboMultiplicity the ccombo that holds the new multiplicity
	 */
	private void setMultiplicityValue(Property property, CCombo comboMultiplicity){
		String selectedMul = comboMultiplicity.getText();
		StringTokenizer mulToken = new StringTokenizer(selectedMul, "..");
		String lower = mulToken.nextToken();
		String upper = lower;
		if(mulToken.countTokens()>0) {
			upper = mulToken.nextToken();
		}

		// property multiplicity settings
		if(lower.equals("*")) {
			upper = "-1";
			lower = "0";
		} else if(upper.equals("*")) {
			upper="-1";
		}
		setMultiplicityValue(property, Integer.parseInt(lower), Integer.parseInt(upper));
	}

	/**
	 * Sets the multiplicity value for the given property
	 * @param property the property for which multiplicity is modified
	 * @param lower the lower value for the property
	 * @param upper the upper value for the property
	 */
	private void setMultiplicityValue(Property property, int lower, int upper){
		property.setLower(lower);
		property.setUpper(upper);
	}

	/*
	 * (non-Javadoc)
	 * @see com.cea.papyrus.core.ui.properties.tabbed.PropertyViewSection#dispose()
	 */
	/**
	 * 
	 */
	public void dispose(){
		super.dispose();
	}

}
